/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tcc.ejb.controleProjeto.controle;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import tcc.ejb.controleProjeto.controle.exceptions.NonexistentEntityException;
import tcc.ejb.controleProjeto.controle.exceptions.PreexistingEntityException;
import tcc.ejb.controleProjeto.entidade.Atividade;
import tcc.ejb.controleProjeto.entidade.Artefato;
import java.util.ArrayList;
import java.util.List;
import tcc.ejb.controleProjeto.entidade.Tarefa;

/**
 *
 * @author Maciel
 */
public class TarefaJpaController {

    public TarefaJpaController() {
        emf = Persistence.createEntityManagerFactory("WebApplication4PU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Tarefa tarefa) throws PreexistingEntityException, Exception {
        if (tarefa.getArtefatoList() == null) {
            tarefa.setArtefatoList(new ArrayList<Artefato>());
        }
        if (tarefa.getTarefaList() == null) {
            tarefa.setTarefaList(new ArrayList<Tarefa>());
        }
        if (tarefa.getTarefaList1() == null) {
            tarefa.setTarefaList1(new ArrayList<Tarefa>());
        }
        if (tarefa.getArtefatoList1() == null) {
            tarefa.setArtefatoList1(new ArrayList<Artefato>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Atividade atividade = tarefa.getAtividade();
            if (atividade != null) {
                atividade = em.getReference(atividade.getClass(), atividade.getId());
                tarefa.setAtividade(atividade);
            }
            List<Artefato> attachedArtefatoList = new ArrayList<Artefato>();
            for (Artefato artefatoListArtefatoToAttach : tarefa.getArtefatoList()) {
                artefatoListArtefatoToAttach = em.getReference(artefatoListArtefatoToAttach.getClass(), artefatoListArtefatoToAttach.getId());
                attachedArtefatoList.add(artefatoListArtefatoToAttach);
            }
            tarefa.setArtefatoList(attachedArtefatoList);
            List<Tarefa> attachedTarefaList = new ArrayList<Tarefa>();
            for (Tarefa tarefaListTarefaToAttach : tarefa.getTarefaList()) {
                tarefaListTarefaToAttach = em.getReference(tarefaListTarefaToAttach.getClass(), tarefaListTarefaToAttach.getId());
                attachedTarefaList.add(tarefaListTarefaToAttach);
            }
            tarefa.setTarefaList(attachedTarefaList);
            List<Tarefa> attachedTarefaList1 = new ArrayList<Tarefa>();
            for (Tarefa tarefaList1TarefaToAttach : tarefa.getTarefaList1()) {
                tarefaList1TarefaToAttach = em.getReference(tarefaList1TarefaToAttach.getClass(), tarefaList1TarefaToAttach.getId());
                attachedTarefaList1.add(tarefaList1TarefaToAttach);
            }
            tarefa.setTarefaList1(attachedTarefaList1);
            List<Artefato> attachedArtefatoList1 = new ArrayList<Artefato>();
            for (Artefato artefatoList1ArtefatoToAttach : tarefa.getArtefatoList1()) {
                artefatoList1ArtefatoToAttach = em.getReference(artefatoList1ArtefatoToAttach.getClass(), artefatoList1ArtefatoToAttach.getId());
                attachedArtefatoList1.add(artefatoList1ArtefatoToAttach);
            }
            tarefa.setArtefatoList1(attachedArtefatoList1);
            em.persist(tarefa);
            if (atividade != null) {
                atividade.getTarefaList().add(tarefa);
                atividade = em.merge(atividade);
            }
            for (Artefato artefatoListArtefato : tarefa.getArtefatoList()) {
                artefatoListArtefato.getTarefaList().add(tarefa);
                artefatoListArtefato = em.merge(artefatoListArtefato);
            }
            for (Tarefa tarefaListTarefa : tarefa.getTarefaList()) {
                tarefaListTarefa.getTarefaList().add(tarefa);
                tarefaListTarefa = em.merge(tarefaListTarefa);
            }
            for (Tarefa tarefaList1Tarefa : tarefa.getTarefaList1()) {
                tarefaList1Tarefa.getTarefaList().add(tarefa);
                tarefaList1Tarefa = em.merge(tarefaList1Tarefa);
            }
            for (Artefato artefatoList1Artefato : tarefa.getArtefatoList1()) {
                artefatoList1Artefato.getTarefaList1().add(tarefa);
                artefatoList1Artefato = em.merge(artefatoList1Artefato);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findTarefa(tarefa.getId()) != null) {
                throw new PreexistingEntityException("Tarefa " + tarefa + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Tarefa tarefa) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Tarefa persistentTarefa = em.find(Tarefa.class, tarefa.getId());
            Atividade atividadeOld = persistentTarefa.getAtividade();
            Atividade atividadeNew = tarefa.getAtividade();
            List<Artefato> artefatoListOld = persistentTarefa.getArtefatoList();
            List<Artefato> artefatoListNew = tarefa.getArtefatoList();
            List<Tarefa> tarefaListOld = persistentTarefa.getTarefaList();
            List<Tarefa> tarefaListNew = tarefa.getTarefaList();
            List<Tarefa> tarefaList1Old = persistentTarefa.getTarefaList1();
            List<Tarefa> tarefaList1New = tarefa.getTarefaList1();
            List<Artefato> artefatoList1Old = persistentTarefa.getArtefatoList1();
            List<Artefato> artefatoList1New = tarefa.getArtefatoList1();
            if (atividadeNew != null) {
                atividadeNew = em.getReference(atividadeNew.getClass(), atividadeNew.getId());
                tarefa.setAtividade(atividadeNew);
            }
            List<Artefato> attachedArtefatoListNew = new ArrayList<Artefato>();
            for (Artefato artefatoListNewArtefatoToAttach : artefatoListNew) {
                artefatoListNewArtefatoToAttach = em.getReference(artefatoListNewArtefatoToAttach.getClass(), artefatoListNewArtefatoToAttach.getId());
                attachedArtefatoListNew.add(artefatoListNewArtefatoToAttach);
            }
            artefatoListNew = attachedArtefatoListNew;
            tarefa.setArtefatoList(artefatoListNew);
            List<Tarefa> attachedTarefaListNew = new ArrayList<Tarefa>();
            for (Tarefa tarefaListNewTarefaToAttach : tarefaListNew) {
                tarefaListNewTarefaToAttach = em.getReference(tarefaListNewTarefaToAttach.getClass(), tarefaListNewTarefaToAttach.getId());
                attachedTarefaListNew.add(tarefaListNewTarefaToAttach);
            }
            tarefaListNew = attachedTarefaListNew;
            tarefa.setTarefaList(tarefaListNew);
            List<Tarefa> attachedTarefaList1New = new ArrayList<Tarefa>();
            for (Tarefa tarefaList1NewTarefaToAttach : tarefaList1New) {
                tarefaList1NewTarefaToAttach = em.getReference(tarefaList1NewTarefaToAttach.getClass(), tarefaList1NewTarefaToAttach.getId());
                attachedTarefaList1New.add(tarefaList1NewTarefaToAttach);
            }
            tarefaList1New = attachedTarefaList1New;
            tarefa.setTarefaList1(tarefaList1New);
            List<Artefato> attachedArtefatoList1New = new ArrayList<Artefato>();
            for (Artefato artefatoList1NewArtefatoToAttach : artefatoList1New) {
                artefatoList1NewArtefatoToAttach = em.getReference(artefatoList1NewArtefatoToAttach.getClass(), artefatoList1NewArtefatoToAttach.getId());
                attachedArtefatoList1New.add(artefatoList1NewArtefatoToAttach);
            }
            artefatoList1New = attachedArtefatoList1New;
            tarefa.setArtefatoList1(artefatoList1New);
            tarefa = em.merge(tarefa);
            if (atividadeOld != null && !atividadeOld.equals(atividadeNew)) {
                atividadeOld.getTarefaList().remove(tarefa);
                atividadeOld = em.merge(atividadeOld);
            }
            if (atividadeNew != null && !atividadeNew.equals(atividadeOld)) {
                atividadeNew.getTarefaList().add(tarefa);
                atividadeNew = em.merge(atividadeNew);
            }
            for (Artefato artefatoListOldArtefato : artefatoListOld) {
                if (!artefatoListNew.contains(artefatoListOldArtefato)) {
                    artefatoListOldArtefato.getTarefaList().remove(tarefa);
                    artefatoListOldArtefato = em.merge(artefatoListOldArtefato);
                }
            }
            for (Artefato artefatoListNewArtefato : artefatoListNew) {
                if (!artefatoListOld.contains(artefatoListNewArtefato)) {
                    artefatoListNewArtefato.getTarefaList().add(tarefa);
                    artefatoListNewArtefato = em.merge(artefatoListNewArtefato);
                }
            }
            for (Tarefa tarefaListOldTarefa : tarefaListOld) {
                if (!tarefaListNew.contains(tarefaListOldTarefa)) {
                    tarefaListOldTarefa.getTarefaList().remove(tarefa);
                    tarefaListOldTarefa = em.merge(tarefaListOldTarefa);
                }
            }
            for (Tarefa tarefaListNewTarefa : tarefaListNew) {
                if (!tarefaListOld.contains(tarefaListNewTarefa)) {
                    tarefaListNewTarefa.getTarefaList().add(tarefa);
                    tarefaListNewTarefa = em.merge(tarefaListNewTarefa);
                }
            }
            for (Tarefa tarefaList1OldTarefa : tarefaList1Old) {
                if (!tarefaList1New.contains(tarefaList1OldTarefa)) {
                    tarefaList1OldTarefa.getTarefaList().remove(tarefa);
                    tarefaList1OldTarefa = em.merge(tarefaList1OldTarefa);
                }
            }
            for (Tarefa tarefaList1NewTarefa : tarefaList1New) {
                if (!tarefaList1Old.contains(tarefaList1NewTarefa)) {
                    tarefaList1NewTarefa.getTarefaList().add(tarefa);
                    tarefaList1NewTarefa = em.merge(tarefaList1NewTarefa);
                }
            }
            for (Artefato artefatoList1OldArtefato : artefatoList1Old) {
                if (!artefatoList1New.contains(artefatoList1OldArtefato)) {
                    artefatoList1OldArtefato.getTarefaList1().remove(tarefa);
                    artefatoList1OldArtefato = em.merge(artefatoList1OldArtefato);
                }
            }
            for (Artefato artefatoList1NewArtefato : artefatoList1New) {
                if (!artefatoList1Old.contains(artefatoList1NewArtefato)) {
                    artefatoList1NewArtefato.getTarefaList1().add(tarefa);
                    artefatoList1NewArtefato = em.merge(artefatoList1NewArtefato);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = tarefa.getId();
                if (findTarefa(id) == null) {
                    throw new NonexistentEntityException("The tarefa with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Tarefa tarefa;
            try {
                tarefa = em.getReference(Tarefa.class, id);
                tarefa.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The tarefa with id " + id + " no longer exists.", enfe);
            }
            Atividade atividade = tarefa.getAtividade();
            if (atividade != null) {
                atividade.getTarefaList().remove(tarefa);
                atividade = em.merge(atividade);
            }
            List<Artefato> artefatoList = tarefa.getArtefatoList();
            for (Artefato artefatoListArtefato : artefatoList) {
                artefatoListArtefato.getTarefaList().remove(tarefa);
                artefatoListArtefato = em.merge(artefatoListArtefato);
            }
            List<Tarefa> tarefaList = tarefa.getTarefaList();
            for (Tarefa tarefaListTarefa : tarefaList) {
                tarefaListTarefa.getTarefaList().remove(tarefa);
                tarefaListTarefa = em.merge(tarefaListTarefa);
            }
            List<Tarefa> tarefaList1 = tarefa.getTarefaList1();
            for (Tarefa tarefaList1Tarefa : tarefaList1) {
                tarefaList1Tarefa.getTarefaList().remove(tarefa);
                tarefaList1Tarefa = em.merge(tarefaList1Tarefa);
            }
            List<Artefato> artefatoList1 = tarefa.getArtefatoList1();
            for (Artefato artefatoList1Artefato : artefatoList1) {
                artefatoList1Artefato.getTarefaList1().remove(tarefa);
                artefatoList1Artefato = em.merge(artefatoList1Artefato);
            }
            em.remove(tarefa);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Tarefa> findTarefaEntities() {
        return findTarefaEntities(true, -1, -1);
    }

    public List<Tarefa> findTarefaEntities(int maxResults, int firstResult) {
        return findTarefaEntities(false, maxResults, firstResult);
    }

    private List<Tarefa> findTarefaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Tarefa.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Tarefa findTarefa(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Tarefa.class, id);
        } finally {
            em.close();
        }
    }

    public int getTarefaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Tarefa> rt = cq.from(Tarefa.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
